package cn.cjxy;

import cn.cjxy.domain.User;
import cn.cjxy.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * service测试类
 */
@SpringBootTest(classes = Spring_MPApp.class)//启动类的字节码文件
@RunWith(SpringRunner.class)
public class Demo2 {

    @Autowired
    private UserService userService;

    /**
     * 修改和新增
     */
    @Test
    public void saveOrUpdate(){
        // TableId 注解属性值存在则更新记录，否插入一条记录
        User user = new User(10L, "tom", "0", 20, "2020-03-06");
        userService.saveOrUpdate(user);
        User user1 = new User(null, "tom11", "0", 22, "2020-03-06");
        userService.saveOrUpdate(user1);
    }

    /**
     * 测试条件构造器
     */
    @Test
    public void allEq(){
        //allEq
        //allEq 方法是 MyBatis-Plus 中用于构建查询条件的方法之一，它允许我们通过一个 Map 来设置多个字段的相等条件。
        //获取条件构造器
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        Map<String, Object> map = new HashMap<>();
        map.put("name", "Rose");//key是数据库的字段  值是对应的字段值
        map.put("age", 21);
        map.put("sex","1");
        //设置查询条件
         userQueryWrapper.allEq(map);
         //执行查询  SELECT id,name,sex,age,birthday FROM user WHERE (sex = ? AND name = ? AND age = ?)
        User one = userService.getOne(userQueryWrapper);
        System.out.println(one);
    }
    //eq  相等
    @Test
    public void eq(){
        //获取条件构造器
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("name", "张三");//第一个参数是数据库的字段  第二个是对应的字段值
        //SELECT id,name,sex,age,birthday FROM user WHERE (name = ?)
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //ne
    //ne 方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一，它用于设置单个字段的不相等条件。
    @Test
    public void ne(){
        //获取条件构造器
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.ne("name", "张三");//第一个参数是数据库的字段  第二个是对应的字段值
        //SELECT id,name,sex,age,birthday FROM user WHERE (name <> ?)
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //between
    //between 方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一，它用于设置单个字段的 BETWEEN 条件
    @Test
    public void between(){
        //获取条件构造器
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //查询年龄在18-25岁之间的用户
        userQueryWrapper.between("age", 18, 25);//第一个参数是数据库的字段 第二个是起始值  第三个是结束值 []
        //SELECT id,name,sex,age,birthday FROM user WHERE (age BETWEEN ? AND ?)
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //like
    //like 方法是 MyBatis-Plus 中用于构建模糊查询条件的基本方法之一，它用于设置单个字段的 LIKE 条件。
    @Test
    public void like(){
        //获取条件构造器
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //查询姓名包含字母o的人
        userQueryWrapper.like("name","o");
        //SELECT id,name,sex,age,birthday FROM user WHERE (name LIKE '%o%')
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //isNull
    //isNull 方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一，它用于设置单个字段的 IS NULL 条件
    @Test
    public void isNull(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //查询age为空的用户
        userQueryWrapper.isNull("age");//参数就是数据库的字段名
        //SELECT id,name,sex,age,birthday FROM user WHERE (age IS NULL)
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //in
    //in 方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一，它用于设置单个字段的 IN 条件，即字段的值在给定的集合中。
    //inSql
    //inSql 方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一，
    // 它用于设置单个字段的 IN 条件，但与 in 方法不同的是，
    // inSql 允许你直接使用 SQL 语句来生成 IN 子句中的值集合
    @Test
    public void in(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //查询年龄在21 22 24的用户
        userQueryWrapper.in("age",21,22,24);//第一个参数是数据库的字段  后续参数为in的条件
        //SELECT id,name,sex,age,birthday FROM user WHERE (age IN (?,?,?))
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //只要带有sql结尾的全是支持子查询的

    //groupBy
    //groupBy 方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一，它用于设置查询结果的分组条件。通过指定一个或多个字段，groupBy 方法可以生成 SQL 语句中的 GROUP BY 子句。
    @Test
    public void groupBy(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //
        //根据年龄分组
        userQueryWrapper.groupBy("sex");
        //分组后再加条件
        userQueryWrapper.having("sex",0);//SELECT id,name,sex,age,birthday FROM user GROUP BY sex having sex=0
        userService.list(userQueryWrapper).forEach(System.out::println);
    }

    //排序 oder by
    @Test
    public void oderBy(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //按照年龄升序排列
        userQueryWrapper.orderByAsc("age");
        userService.list(userQueryWrapper).forEach(System.out::println);
    }
    //多条件拼接
    //1.and拼接条件
    @Test
    public void testAnd(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //默认情况下，多条件是and拼接
        //SELECT id,name,sex,age,birthday FROM user WHERE (name LIKE ? AND age < ? AND sex = ?)
        userQueryWrapper.like("name","e")
                        .lt("age",25)
                        .eq("sex","1");

        userService.list(userQueryWrapper).forEach(System.out::println);
    }

    //2.or拼接条件
    @Test
    public void testOr(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //SELECT id,name,sex,age,birthday FROM user WHERE (name LIKE ? OR age < ? AND sex = ?)
        userQueryWrapper.like("name","e")
                .or()
                .lt("age",25)
                .eq("sex","1");//此处还是and
        userService.list(userQueryWrapper).forEach(System.out::println);
    }

    //3.其他方法
    @Test
    public void testOther1(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lt("age",25);
        // and方法  用于拼接一个其他的整体条件
     /*   wrapper.nested(new Consumer<QueryWrapper<User>>() {
            @Override
            public void accept(QueryWrapper<User> userQueryWrapper) {
                //相当于and方法
            }
        });*/
        wrapper.and(new Consumer<QueryWrapper<User>>() {
            @Override
            public void accept(QueryWrapper<User> userQueryWrapper) {
                userQueryWrapper.eq("sex","0")
                                 .or()
                                 .like("name","o");
            }
        });
        //SELECT id,name,sex,age,birthday FROM user WHERE (age < ? AND (sex = ? OR name LIKE ?))
        userService.list(wrapper).forEach(System.out::println);
    }
    //func方法：用于多条件的拼接
    @Test
    public void testOther2(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lt("age",25);
        wrapper.func(new Consumer<QueryWrapper<User>>() {
            @Override
            public void accept(QueryWrapper<User> userQueryWrapper) {
                userQueryWrapper.like("name","o");
                userQueryWrapper.eq("sex","0");
            }
        });
        //相当于userQueryWrapper.like("name","o").eq("sex","0").lt("age",25);；
        //SELECT id,name,sex,age,birthday FROM user WHERE (age < ? AND name LIKE ? AND sex = ?)
        userService.list(wrapper).forEach(System.out::println);
    }

    //apply方法 可以使用占位符传参
    @Test
    public void testOther3(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //SELECT id,name,sex,age,birthday FROM user WHERE (date_format(birthday,'%Y-%m-%d')=?)
        wrapper.apply("date_format(birthday,'%Y-%m-%d')={0}","2020-02-02");
        userService.list(wrapper).forEach(System.out::println);
    }
    //last方法 无视sql优化规则直接拼接到sql的最后，只能调用一次，直接在sql后加东西；不能防止sql注入e
    //exists方法：  notExists方法
    @Test
    public void testOther4(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.exists("select 1");
        //SELECT id,name,sex,age,birthday FROM user WHERE (EXISTS (select 1))
        userService.list(wrapper).forEach(System.out::println);
    }
    //查询具体的字段
    //QueryWrapper的独有方法
    //select(String sqlSelect)  设置查询字段
    @Test
    public void testOther5(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //SELECT name,age FROM user WHERE (name LIKE ?)
        wrapper.select("name","age")
                .like("name","o");
        userService.list(wrapper).forEach(System.out::println);
    }

}
